//
//  LinkListQueue.swift
//  queue
//
//  Created by lhc on 2023/9/6.
//

import Foundation

class Node<T> {
    var e: T
    var next: Node?
    
    init(e: T, next: Node? = nil) {
        self.e = e
        self.next = next
    }
}

class LinkListQueue<T> {
    
    
    private var head: Node<T>?
    private var tail: Node<T>?
    private var size: Int
    
    init() {
        self.size = 0
    }
    
    func isEmpty() -> Bool {
        return self.size == 0
    }
    
    func getSize() -> Int {
        return self.size
    }
    
    func enqueue(element: T) {
        let node = Node(e: element)
        
        if isEmpty() {
            self.head = node
            self.tail = node
        }else {
            self.tail?.next = node
            self.tail = node
        }
        self.size += 1
    }
    
    func dequeue() -> T? {
        if isEmpty() {
            return nil
        }else if getSize() == 1 {
            let returnNode = self.head
            self.head = nil
            self.tail = nil
            self.size -= 1
            return returnNode?.e
        }else {
            let returnNode = self.head
            self.head = returnNode?.next
            returnNode?.next = nil
            self.size -= 1
            return returnNode?.e
        }
    }
    
    func peek() -> T? {
        if isEmpty() {
            return nil
        }else {
            return self.head?.e
        }
    }
}

extension LinkListQueue: CustomStringConvertible {
    var description: String {
        var temp = "Queue: ["
        guard !isEmpty() else { return "\(temp) ]" }
        
        var cur = self.head
        for _ in 0..<self.size {
            temp += "\(cur!.e) -> "
            cur = cur?.next
        }
        temp += "Nil]"
        return temp
    }
}
